<?php
namespace voxfa\system\process;

/**
 * Process reference
 * @author sonic
 * @date  2010-2-10  下午03:10:20
 */
class Process {
	
	private $handle;
	private $cmd;
	private $descriptorspec;
	private $cwd;
	private $pipes;
	private $status;
	
	public function __construct($cmd,$descriptorspec,$cwd) {
		$this->cmd = $cmd;
		$this->descriptorspec = $descriptorspec;
		$this->cwd = $cwd;
	}
	
	/**
	 * open the current Process
	 */
	public function open() {
		$this->validate();
		$handle = proc_open($this->cmd,$this->descriptorspec,$this->pipes,$this->cwd);
		if(is_resource($handle))
			$this->handle = $handle;
	}
	
	public function getError(){
		return stream_get_contents($this->pipes['2']);
	}
	
	public function getOutput(){
		return stream_get_contents($this->pipes['1']);	
	}
	
	public function setInput($input) {
		fwrite($this->pipes['1'],$input);
	}
	
	public function isRun(){
		$this->flushStatus();
		return $this->status['running'];
	}
	
	public function getExitcode(){
		$this->flushStatus();
		return $this->status['exitcode'];
	}
	
	public function getPid(){
		$this->flushStatus();
		return $this->status['pid'];
	}
	
	public function getCommand(){
		$this->flushStatus();
		return $this->status['command'];
	}

	/**
	 * close Process;
	 * @return exitcode;
	 */
	public function close() {
		foreach($this->pipes as $pipe){
			fclose($pipe);
		}
		return proc_close($this->handle);
	}
	
	/**
	 * terminate
	 */
	public function terminate(){
		return proc_terminate($this->handle);
	}
	
	private function validate() {
		if (!array_key_exists('0',$$this->descriptorsec))
			throw new RuntimeException("descriptorsec input must set! ");
		if (!array_key_exists('1',$this->descriptorsec))
			throw new RuntimeException("descriptorsec output must set! ");
		if (!array_key_exists('2',$this->descriptorsec))
			throw new RuntimeException("descriptorsec error must set! ");
	}
	
	private function flushStatus(){
		$this->status = proc_get_status($this->handle);	
	}
}